package
{
	import flash.desktop.NativeProcess;
	import flash.desktop.NativeProcessStartupInfo;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.TimerEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	import flash.utils.Timer;
	import flash.utils.setTimeout;
	
	import mx.graphics.codec.JPEGEncoder;
	import mx.graphics.codec.PNGEncoder;
	
	import spark.components.Label;
	
	public class Ani_compress
	{
		private static var _ins:Ani_compress;
		
		public static var exportUrl:String;
		public static var importRoot:String;
		public static var printMsg:Label;
		
		public static var dataDic:Object = {};
		
		private var _cfgStream:FileStream;
		private var _urlLoader:URLLoader;
		
		public var resType:int = 2;
		private var _path:String;
		private var _dataPath:String;
		private var _rootPath:String;
		private var _outPathDic:Object = {};
		private var _pngArr:Array = [];//已压缩好的PNG数组
		
		private var _subDirec:String;
		
		private var _timer:Timer;
		private var _timer2:Timer;
		private var _ani:Animator;
		private var _loadedCount:int = 0;
		
		public static function get ins():Ani_compress
		{
			if(!_ins){
				_ins = new Ani_compress();
			}
			return _ins;
		}
		
		public function Ani_compress()
		{
		}
		public function doLoad(path:String):void
		{
			//"C:\Users\Administrator\Desktop\ani原始\21000\bg_tiles\1.mp"//路径格式是这样的而已
			
			_path = path;
			
			loadData();
		}
		/**
		 * 如果有地图数据，则加载
		 */
		private function loadData():void
		{
			if(_path){
//				if(dataDic[_dataPath]){
//					_mapData = dataDic[_dataPath];
//					loadClip();
//					return;
//				}
				var request:URLRequest = new URLRequest(_path);
				_urlLoader = new URLLoader();
				_urlLoader.addEventListener(Event.COMPLETE, onComplete1);
				_urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onLoadError1);
				_urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onLoadError2);
				_urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoadError2);
				_urlLoader.data = null;
				_urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
				_urlLoader.load(request);
			}
			else{
//				loadClip();
			}
		}
		private function onComplete1(e:Event):void
		{
			_urlLoader.removeEventListener(Event.COMPLETE, onComplete1);
			_urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, onLoadError1);
			_urlLoader.removeEventListener(HTTPStatusEvent.HTTP_STATUS, onLoadError2);
			_urlLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoadError2);
			
			var bytes:ByteArray = (_urlLoader.data);
			parser(bytes);
			
		}
		private function onLoadError1(e:Event):void
		{
			trace("加载是失败");
//			loadClip();
		}
		private function onLoadError2(e:Event):void
		{
			trace("加载是失败2");
		}
		
		public function parser(bytes:ByteArray):void
		{
			var img:* = null;
			var bmdByte:* = null;
			var i:int;
			var ani:Animator = new Animator();
			bytes.position = (bytes.length - 3);
			var key:String = bytes.readMultiByte(3, "utf-8");
			if (key != "YER")
			{
				ani.YER = "";
				
				bytes.uncompress();
				bytes.position = bytes.length;
				bytes.writeMultiByte("YER", "utf-8");
			}
			else{
				ani.YER = "YER";
			}
			bytes.position = 0;
			var memory:* = 0;
			_ani = ani;
			var blendMode:String = bytes.readUTF();
			var length:int = bytes.readByte();
			i = 0;
			var p:String = _path.substring(_path.lastIndexOf("\\") + 1);
			p = p.replace(".ani", "");
			while (i < length)
			{
				img = new SingleImage();
				img.offsetX = bytes.readShort();
				img.offsetY = bytes.readShort();
				img.delayTime = bytes.readInt();
				img.imageName = bytes.readUTF();
				img.offsetX2 = bytes.readShort();
				img.offsetY2 = bytes.readShort();
				bmdByte = new ByteArray();
				bytes.readBytes(bmdByte, 0, bytes.readInt());
				img.bitmapData = byteToBitmap(bmdByte);
				ani.pushImage(img);
				memory = (memory + ((img.bitmapData.width * img.bitmapData.height) * 4));
				i++;
				
				writeImg(img.bitmapData, p + "_" + i + ".png");
			};
			ani.blendMode = blendMode;
			
//			onFinish(ani, memory); //not popped
		}
		public static function byteToBitmap(bytes:ByteArray, uncompress:Boolean=true):BitmapData
		{
			if (uncompress)
			{
				bytes.uncompress();
			};
			bytes.position = 0;
			var width:int = bytes.readUnsignedInt();
			var height:int = (((bytes.length - 4) / 4) / width);
			var bmd:BitmapData = new BitmapData(width, height, true, 0);
			bmd.setPixels(bmd.rect, bytes);
			return (bmd);
		}
		
		
		//------------output=------------------------
		public function writeImg(param1:BitmapData, path:String):void
		{
//			var path:String = _path.replace(importRoot, "");
//			if(path.indexOf("\\") == 0){
//				path = path.substring(1);
//			}
			
			var imgByteArray:ByteArray;
			var jpgenc:JPEGEncoder;
			var pngenc:PNGEncoder;
			var msg:Label;
			var bmd:BitmapData = param1;
			var laststr:String;
			if(resType == 1)//从json拆分
			{
				jpgenc = new JPEGEncoder(80);
				imgByteArray = jpgenc.encode(bmd);
				path = path.replace(".mp", ".jpg");
			}
			else
			{
				pngenc = new PNGEncoder();
				imgByteArray = pngenc.encode(bmd);
				path = path.replace(".mp", ".png");
			}
			_outPathDic[path] = false;
			
			var rootFile:File = new File(curExportUrl);
			var fl:File = rootFile.resolvePath(path);
			var fs:FileStream = new FileStream();
			
			try
			{
				fs.open(fl, FileMode.WRITE);
				fs.writeBytes(imgByteArray);
				fs.close();
				
				if(!_timer){
					_timer = new Timer(100);
					_timer.addEventListener(TimerEvent.TIMER, onTimer);
					_timer.start();
				}
			}
			catch(e:Error)
			{
				throw new Error("打包出错：" + path);
			}
		}
		private function get curExportUrl():String
		{
			if(_path.indexOf(importRoot) == -1){
				return exportUrl;
			}
			var p:String = _path.replace(importRoot, "");
			var index:int = p.lastIndexOf("\\");
			if(index != -1){
				p = p.substring(0, index);
			}
			return exportUrl + p;
		}
		private function onTimer(e:TimerEvent):void
		{
			for(var key:String in _outPathDic){
				var rootFile:File = new File(curExportUrl);
				var fl:File = rootFile.resolvePath(key);
				
				if(fl.exists && _outPathDic[key] == false){
					
					_outPathDic[key] = true;
					
					var f:File = new File("d:/pngquant/pngquant.exe");// File.applicationDirectory;
					f = f.resolvePath("d:/pngquant/pngquant.exe");
					var na:NativeProcessStartupInfo = new NativeProcessStartupInfo();//AIR2.0中的新类, 创建进程的信息对象
					na.executable = f;// 将你指定的MyFile对象指定为可执行文件
					var arr:Vector.<String> = new Vector.<String>();
					//				arr.push("D:/pngquant/2010_tx10.ani.png");
					
					var path:String = fl.nativePath.replace(/\\/gi, "\/");
					arr.push(path);
					na.arguments = arr;
					var process:NativeProcess = new NativeProcess;// 创建一个本地进程
					process.start(na);// 运行本地进程
					
					if(!_timer2){
						_timer2 = new Timer(100);
						_timer2.addEventListener(TimerEvent.TIMER, onTimer2);
						_timer2.start();
					}
				}
			}
		}
		private function onTimer2(e:TimerEvent):void
		{
			for(var key:String in _outPathDic){
				var fix:String = key.substring(key.lastIndexOf("."));
				var path:String = key.replace(fix, "-fs8" + fix);
				
				var rootFile:File = new File(curExportUrl);
				var fl:File = rootFile.resolvePath(path);
				if(fl.exists && _outPathDic[key] != 2){
					
					_outPathDic[key] = 2;
					
					var rootFile2:File = new File(curExportUrl);
					var fl2:File = rootFile2.resolvePath(key);
					
					fl.moveTo(fl2, true);
//					fl.copyTo(fl2, true);////
				}
			}
			
			var count:int = 0;
			for each(var value:int in _outPathDic){
				if(value == 2){
					count ++;
				}
			}
			
			if(count >= _ani.length){//说明图片已压缩并剪切好
				setTimeout(onStartCompress, 500 + Math.random() * 2000);
				_timer2.stop();
				_timer2.removeEventListener(TimerEvent.TIMER, onTimer2);
				_timer.stop();
				_timer.removeEventListener(TimerEvent.TIMER, onTimer);
			}
		}
		private function onStartCompress():void
		{
			_timer2.addEventListener(TimerEvent.TIMER, onTimer3);
			_timer2.start();
		}
		
		private function onTimer3(e:TimerEvent):void
		{
			for(var key:String in _outPathDic){
				
				var fix2:String = key.substring(key.lastIndexOf("."));
				var path2:String = key.replace(fix2, "-fs8" + fix2);
				var rootFile2:File = new File(curExportUrl);
				var fl2:File = rootFile2.resolvePath(path2);
				
				var rootFile:File = new File(curExportUrl);
				var fl:File = rootFile.resolvePath(key);
				
				if(!fl2.exists && fl.exists && _outPathDic[key] != 3){
					
					_outPathDic[key] = 3;
					
					var path:String = fl.nativePath.replace(/\\/gi, "\/");
					var index:int = parseInt(path.substring(path.lastIndexOf("_") + 1, path.lastIndexOf(".")));
					index -= 1;
					var loader:Ani_compress_loader = new Ani_compress_loader(onPngLoaded);
					loader.path = path;
					loader.index = index;
					loader.startLoad();
				}
			}
		}
		private function onPngLoaded(byte:ByteArray, index:int):void
		{
			_pngArr[index] = byte;
			
			_loadedCount ++;
			
			if(_loadedCount >= _ani.length){
				
				_timer2.stop();
				_timer2.removeEventListener(TimerEvent.TIMER, onTimer3);
				
				deletePng();
				outputAni();
			}
		}
		private function deletePng():void
		{
			for(var key:String in _outPathDic){
				
				var rootFile:File = new File(curExportUrl);
				var fl:File = rootFile.resolvePath(key);
				
				if(fl.exists){
					
					fl.deleteFile();
				}
			}
		}
		private function outputAni():void
		{
			var img:SingleImage;
			var bytes:ByteArray = new ByteArray();
			bytes.position = 0;
			bytes.writeUTF(_ani.blendMode);
			bytes.writeByte(_ani.length);
			var imgByte:ByteArray;
			for(var i:int=0; i<_ani.length; i++){
				img = _ani.list[i];
				bytes.writeShort(img.offsetX);
				bytes.writeShort(img.offsetY);
				bytes.writeInt(img.delayTime);
				bytes.writeUTF(img.imageName);
				bytes.writeShort(img.offsetX2);
				bytes.writeShort(img.offsetY2);
				
				imgByte = new ByteArray();
				imgByte.writeUnsignedInt(img.bitmapData.width);
				imgByte.writeBytes(_pngArr[i]);
				imgByte.position = 0;
				imgByte.compress();
				bytes.writeInt(imgByte.length);
				bytes.writeBytes(imgByte);
			}
			bytes.position = 0;
			
			if(_ani.YER){
				bytes.writeMultiByte("YER", "utf-8");
			}
			else{
				bytes.compress();
			}
			bytes.position = 0;
			
			
			var rootFile:File = new File(curExportUrl);
			var path:String = _path.substring(_path.lastIndexOf("\\") + 1);
			var fl:File = rootFile.resolvePath(path);
			var fs:FileStream = new FileStream();
			
			try
			{
				fs.open(fl, FileMode.WRITE);
				fs.writeBytes(bytes);
				fs.close();
				
			}
			catch(e:Error)
			{
				throw new Error("打包出错：" + path);
			}
			
		}
		
		
	}
}
import flash.display.BitmapData;

class Animator
{
	
	private var _totalMovieTime:int = 1;
	private var _isDispose:Boolean = false;
	private var _blendMode:String = "normal";
	private var _url:String;
	private var _currentFrame:int = -1;
	private var _delay:int = 0;
	private var _list:Array;
	private var _parmas:Object;
	private var _loop:Boolean;
	private var _width:int = -1;
	private var _height:int = -1;
	
	public var YER:String = "";
	
	public function get list():Array
	{
		return _list;
	}
	
	public function Animator()
	{
		this._list = [];
	}
	public function addImageAt(image:SingleImage, index:int):void
	{
		image.animator = this;
		this._list.splice(index, 0, image);
	}
	public function replaceImageAt(image:SingleImage, index:int):void
	{
		image.animator = this;
		this._list[index] = image;
	}
	public function pushImage(image:SingleImage):uint
	{
		image.animator = this;
		this._totalMovieTime = (this._totalMovieTime + image.delayTime);
		return (this._list.push(image));
	}
	public function getImage(index:uint):SingleImage
	{
		if (this._list)
		{
			return (this._list[index]);
		};
		return (null);
	}
	public function get width():int
	{
		var image:* = null;
		var w:int;
		if (this._width == -1)
		{
			for each (image in this._list)
			{
				w = (image.width + image.offsetX);
				if (this._width < w)
				{
					this._width = w;
				};
			};
		};
		return (this._width);
	}
	public function get height():int
	{
		var image:* = null;
		var h:int;
		if (this._height == -1)
		{
			for each (image in this._list)
			{
				h = (image.height + image.offsetY);
				if (this._height < h)
				{
					this._height = h;
				};
			};
		};
		return (this._height);
	}
	public function get totalMovieTime():int
	{
		return (this._totalMovieTime);
	}
	public function get length():uint
	{
		return (this._list.length);
	}
	public function get renderDelay():int
	{
		return (this._delay);
	}
	public function set renderDelay(value:int):void
	{
		this._delay = value;
	}
	public function get url():String
	{
		return (this._url);
	}
	public function set url(value:String):void
	{
		this._url = value;
	}
	public function get parmas():Object
	{
		return (this._parmas);
	}
	public function set parmas(value:Object):void
	{
		this._parmas = value;
	}
	public function get loop():Boolean
	{
		return (this._loop);
	}
	public function set loop(value:Boolean):void
	{
		this._loop = value;
	}
	public function get blendMode():String
	{
		return (this._blendMode);
	}
	public function set blendMode(value:String):void
	{
		this._blendMode = value;
	}
	public function get isDispose():Boolean
	{
		return (this._isDispose);
	}
	public function dispose():void
	{
		var image:* = null;
		var i:int;
		var leng:int = this._list.length;
		while (i < leng)
		{
			image = this._list[i];
			image.dispose();
			i++;
		};
		this._list = null;
		this._isDispose = true;
	}
	
}



class SingleImage
{
	
	public var bitmapData:BitmapData;
	public var width:Number = 0;
	public var height:Number = 0;
	public var offsetX:Number = 0;
	public var offsetY:Number = 0;
	public var offsetX2:Number = 0;
	public var offsetY2:Number = 0;
	public var frameNum:int;
	public var imageName:String;
	public var delayTime:int = 0;
	public var animator:Animator;
	protected var _isDispose:Boolean = false;
	
	public function SingleImage(bitmapdata:BitmapData=null)
	{
		this.bitmapData = bitmapdata;
		if (this.bitmapData)
		{
			this.width = this.bitmapData.width;
			this.height = this.bitmapData.height;
		};
	}
	public function get isDispose():Boolean
	{
		return (this._isDispose);
	}
	public function dispose():void
	{
		if (this.bitmapData)
		{
			this.bitmapData.dispose();
		};
		this.bitmapData = null;
		this.width = 0;
		this.height = 0;
		this.offsetX = 0;
		this.offsetY = 0;
		this.frameNum = 0;
		this.imageName = "";
		this.animator = null;
		this._isDispose = true;
	}
	
}